import {Box, FormControl, FormHelperText, Input, InputAdornment, InputLabel} from "@mui/material";
import {ChangeEventHandler, FC, useEffect, useState} from "react";
import {useNavigate} from "react-router-dom";
import IconButton from "@mui/material/IconButton";
import {Visibility, VisibilityOff} from "@mui/icons-material";
import AppProvider from "../../../sources/AppProvider.ts";
import DGConnect from "../../../sources/DGConnect.ts";
import {Util} from "../../../sources/Util.ts";
import DGToast from "../../../components/DGToast.tsx";
import {AlertColor} from "@mui/material/Alert/Alert";
import DGDialogLayout from "../../../components/DGDialogLayout/DGDialogLayout.tsx";
import DGDrawerLayout from "../../../components/DGDrawerLayout/DGDrawerLayout.tsx";
import DGTextView from "../../../components/DGTextView.tsx";


interface ChangePasswordProps {
    state: boolean,
    close: () => void,
}

interface DGToastProps {
    state: boolean,
    severity: AlertColor,
    text: string
}

const ChangePassword: FC<ChangePasswordProps> = ({state, close}) => {
    // 获取程序上下文
    const App = AppProvider.useAppContext();
    // 路由跳转
    const router = useNavigate();
    // Toast 弹窗
    const [toast, setToast] = useState<DGToastProps>({state: false, severity: "info", text: ""});

    // 设置加载状态
    const [loading, setLoading] = useState(false);

    // 新密码信息
    const [newPassword, setNewPassword] = useState("");
    // 新密码显示状态
    const [showNewPassword, setShowNewPassword] = useState(false);
    // 新密码错误信息
    const [newPasswordError, setNewPasswordError] = useState({state: false, text: ""});

    // 确认密码信息
    const [comPassword, setComPassword] = useState("");
    // 确认密码显示状态
    const [showComPassword, setShowComPassword] = useState(false);
    // 新密码错误信息
    const [comPasswordError, setComPasswordError] = useState({state: false, text: ""});

    // 旧密码信息
    const [oldPassword, setOldPassword] = useState("");
    // 旧密码显示状态
    const [showOldPassword, setShowOldPassword] = useState(false);
    // 新密码错误信息
    const [oldPasswordError, setOldPasswordError] = useState({state: false, text: ""});

    // 关闭函数
    const handleClose = (id: number) => {
        if (!loading) {
            // 关闭面板
            close();
            // 后退
            if (id === 1) router(-1);
        }
    }


    // 新密码更改函数
    const handleChangeNewPassword: ChangeEventHandler<HTMLInputElement> = e => {
        // 清空新密码错误信息
        setNewPasswordError({state: false, text: ""});
        // 设置新密码信息
        setNewPassword(e.target.value);
        // 判断新密码是否低于 6 位
        if (e.target.value !== "" && e.target.value.length < 6) return setNewPasswordError({
            state: true, text: "新密码不能低于 6 位！"
        });
        // 判断新密码是否高于 18 位
        if (e.target.value !== "" && e.target.value.length > 18) return setNewPasswordError({
            state: true, text: "不能大于 18 位！"
        });
    }


    // 确认密码更改函数
    const handleChangeComPassword: ChangeEventHandler<HTMLInputElement> = e => {
        // 清空确认密码错误信息
        setComPasswordError({state: false, text: ""});
        // 设置确认密码信息
        setComPassword(e.target.value);
        // 判断确认密码是否和新密码一致
        if (e.target.value !== newPassword) {
            return setComPasswordError({state: true, text: "确认密码和新密码不一致！"});
        }
    }


    // 旧密码更改函数
    const handleChangeOldPassword: ChangeEventHandler<HTMLInputElement> = e => {
        // 清空旧密码错误信息
        setOldPasswordError({state: false, text: ""});
        //设置旧密码信息
        setOldPassword(e.target.value);
    }


    // 提交函数
    const handleSubmit = () => {
        // 清空新密码错误信息
        setNewPasswordError({state: false, text: ""});
        // 清空确认密码错误信息
        setComPasswordError({state: false, text: ""});
        // 清空旧密码错误信息
        setOldPasswordError({state: false, text: ""});
        // 判断新密码是否输入为空
        if (newPassword === "") return setNewPasswordError({state: true, text: "新密码不能为空！"});
        // 判断新密码输入是否低于 6 位
        if (newPassword !== "" && newPassword.length < 6) return setNewPasswordError({
            state: true, text: "新密码不能低于 6 位！"
        });
        // 判断新密码是否高于 18 位
        if (newPassword !== "" && newPassword.length > 18) return setNewPasswordError({
            state: true, text: "新密码不能大于 18 位！"
        });
        // 判断确认密码是否和新密码一致
        if (comPassword !== newPassword) return setComPasswordError({state: true, text: "确认密码和新密码不一致！"});
        // 判断旧密码是否输入为空
        if (oldPassword === "") return setOldPasswordError({state: true, text: "旧密码不能为空！"});
        //开始加载
        setLoading(true);
        // 发起更改密码请求
        DGConnect.POST(JSON.stringify({
            info: "changePassword", pwd: oldPassword, pwd1: newPassword, pwd2: comPassword
        }), result => {
            // 关闭加载
            setLoading(false);
            // 判断错误信息
            if (result['data']['code'] !== 200) {
                // 判断新密码错误信息
                if ([201, 202, 203, 208].includes(result['data']['code'])) return setNewPasswordError({
                    state: true, text: result['data']['message'] + "错误码：" + result["data"]["code"]
                });
                // 判断确认密码错误信息
                if (result['data']['code'] === 204) return setComPasswordError({
                    state: true, text: result['data']['message'] + "错误码：" + result["data"]["code"]
                });
                // 剩余错误信息通过旧密码错误信息显示
                return setOldPasswordError({
                    state: true, text: result['data']['message'] + "错误码：" + result["data"]["code"]
                });
            }
            // 获取本地信息
            const userInfo = Util.Storage.getLocal("LOGIN-USER");
            // 更新存储在本地的密码
            Util.Storage.setLocal("LOGIN-USER", {username: userInfo['username'], password: newPassword});
            // 更新会话信息
            App!.setUserInfo(result['data']['result']);
            // 提示修改完成
            setToast({state: true, severity: "success", text: "密码更改成功！"});
            // 关闭弹窗
            setTimeout(() => handleClose(1), 500);
        }, error => {
            // 关闭加载
            setLoading(false);
            // 提示更改失败
            setOldPasswordError({
                state: true, text: "遇到了一些问题，请尝试重试，或者及时联系我们！错误信息：" + error['stack']
            });
        });

    }
    // 加载返回和后退识别
    useEffect(() => {
        // 清空新密码信息
        setNewPassword("");
        // 清空确认密码信息
        setComPassword("");
        // 清空旧密码信息
        setOldPassword("");
        // 清空新密码错误信息
        setNewPasswordError({state: false, text: ""});
        // 清空确认密码错误信息
        setComPasswordError({state: false, text: ""});
        // 清空旧密码错误信息
        setOldPasswordError({state: false, text: ""});
    }, [state]);


    const ContentView = (<>
        {/* 未登录提示语 */}
        {!App!.info && <DGTextView Body Bold>您当前未登陆账户，服务不可用！</DGTextView>}
        {/* 已登录 */}
        {App!.info && <Box>
            {/* 提示语 */}
            <DGTextView Body Bold>新密码的要求为在 6 到 18 位之间的任意字符。请妥善保管您的密码！</DGTextView>
            {/* 新密码输入框控制器 */}
            <FormControl
                margin="dense" variant="standard" disabled={loading}
                error={newPasswordError.state} autoFocus fullWidth required>
                {/* 新密码提示语 */}
                <InputLabel>请输入新密码：</InputLabel>
                {/* 新密码输入框 */}
                <Input
                    type={showNewPassword ? 'text' : 'password'} autoComplete="current-password" value={newPassword}
                    onChange={handleChangeNewPassword} endAdornment={<InputAdornment position="end">
                    {/* 显示、隐藏密码图标按钮 */}
                    <IconButton
                        disabled={loading} onClick={() => setShowNewPassword(!showNewPassword)}
                        onMouseDown={e => e.preventDefault()}>
                        {showNewPassword ? <VisibilityOff/> : <Visibility/>}
                    </IconButton>
                </InputAdornment>}/>
                {/* 新密码错误信息 */}
                <FormHelperText>{newPasswordError.text}</FormHelperText>
            </FormControl>
            {/* 确认密码输入框控制器 */}
            <FormControl
                margin="dense" variant="standard" disabled={loading}
                error={comPasswordError.state} autoFocus fullWidth required>
                {/* 确认密码提示语 */}
                <InputLabel>请输入确认密码：</InputLabel>
                {/* 确认密码输入框 */}
                <Input
                    type={showComPassword ? 'text' : 'password'} autoComplete="current-password" value={comPassword}
                    onChange={handleChangeComPassword} endAdornment={<InputAdornment position="end">
                    {/* 显示、隐藏密码图标按钮 */}
                    <IconButton
                        disabled={loading} onClick={() => setShowComPassword(!showComPassword)}
                        onMouseDown={e => e.preventDefault()}>
                        {showComPassword ? <VisibilityOff/> : <Visibility/>}
                    </IconButton>
                </InputAdornment>}/>
                {/* 确认密码错误信息 */}
                <FormHelperText>{comPasswordError.text}</FormHelperText>
            </FormControl>
            {/* 旧密码输入框控制器 */}
            <FormControl
                margin="dense" variant="standard" disabled={loading}
                error={oldPasswordError.state} autoFocus fullWidth required>
                {/* 旧密码提示语 */}
                <InputLabel>请输入旧密码进行验证：</InputLabel>
                {/* 旧密码输入框 */}
                <Input
                    type={showOldPassword ? 'text' : 'password'} autoComplete="current-password" value={oldPassword}
                    onChange={handleChangeOldPassword} endAdornment={<InputAdornment position="end">
                    {/* 显示、隐藏密码图标按钮 */}
                    <IconButton
                        disabled={loading} onClick={() => setShowOldPassword(!showOldPassword)}
                        onMouseDown={e => e.preventDefault()}>
                        {showOldPassword ? <VisibilityOff/> : <Visibility/>}
                    </IconButton>
                </InputAdornment>}/>
                {/* 旧密码错误信息 */}
                <FormHelperText>{oldPasswordError.text}</FormHelperText>
            </FormControl>
        </Box>}
    </>);
    return (<Box>
        {/* Toast 组件 */}
        <DGToast state={toast} close={() => setToast({state: false, severity: toast.severity, text: toast.text})}/>
        {/* DGDialogLayout 样式 */}
        <DGDialogLayout
            submit={App!.info ? {name: "确定", click: handleSubmit} : undefined} load={loading}
            title="更改密码" state={state} close={() => handleClose(1)} PANEL AUTO>
            {ContentView}
        </DGDialogLayout>
        {/* DGDrawerLayout 样式 */}
        <DGDrawerLayout
            submit={App!.info ? {name: "确定", click: handleSubmit} : undefined} load={loading}
            title="更改密码" state={state} close={() => handleClose(1)} flex="bottom" PANEL AUTO>
            {ContentView}
        </DGDrawerLayout>


    </Box>);
}

export default ChangePassword;